import type { RouteRecordRaw } from 'vue-router'
import router from '@/router'
import { usePermissionStore, useUserStore } from '@/store'
import NProgress from '@/utils/nprogress'
import { TOKEN_KEY } from '@/enums/CacheEnum'

// 是否有权限
export function hasAuth(
  value: string | string[],
  type: 'button' | 'role' = 'button',
) {
  const { roles, perms } = useUserStore().user
  // 「超级管理员」拥有所有的按钮权限
  if (type === 'button' && roles.includes('ROOT'))
    return true

  const auths = type === 'button' ? perms : roles
  return typeof value === 'string'
    ? auths.includes(value)
    : auths.some((perm) => {
      return value.includes(perm)
    })
}

export function setupPermission() {
  // 白名单路由
  const whiteList = ['/login']

  router.beforeEach(async (to, from, next) => {
    NProgress.start()
    const hasToken = localStorage.getItem(TOKEN_KEY)
    if (hasToken) {
      if (to.path === '/login') {
        // 如果已登录，跳转首页
        next({ path: '/' })
        NProgress.done()
      }
      else {
        const userStore = useUserStore()
        const hasRoles
          = userStore.user.roles && userStore.user.roles.length > 0
        if (hasRoles) {
          // 未匹配到任何路由，跳转404
          if (to.matched.length === 0)
            from.name ? next({ name: from.name }) : next('/404')
          else
            next()
        }
        else {
          const permissionStore = usePermissionStore()
          try {
            const { roles } = await userStore.getUserInfo()
            const accessRoutes = await permissionStore.generateRoutes(roles)
            accessRoutes.forEach((route: RouteRecordRaw) => {
              router.addRoute(route)
            })
            next({ ...to, replace: true })
          }
          catch (error) {
            // 移除 token 并跳转登录页
            await userStore.resetToken()
            next(`/login?redirect=${to.path}`)
            NProgress.done()
          }
        }
      }
    }
    else {
      // 未登录可以访问白名单页面
      if (whiteList.includes(to.path)) {
        next()
      }
      else {
        next(`/login?redirect=${to.path}`)
        NProgress.done()
      }
    }
  })

  router.afterEach(() => {
    NProgress.done()
  })
}
